winbrew_app\operations\repair/
cleanup.rs

1use anyhow::{Context, Result};
2use std::fs;
3use std::io::ErrorKind;
4use std::path::PathBuf;
5
6pub fn cleanup_orphan_install_dirs(orphan_paths: &[PathBuf]) -> Result<usize> {
7    let mut removed = 0usize;
8
9    for orphan_path in orphan_paths {
10        match fs::remove_dir_all(orphan_path) {
11            Ok(()) => {
12                removed += 1;
13            }
14            Err(err) if err.kind() == ErrorKind::NotFound => continue,
15            Err(err) => {
16                return Err(err).with_context(|| {
17                    format!(
18                        "failed to remove orphan install directory at {}",
19                        orphan_path.display()
20                    )
21                });
22            }
23        }
24    }
25
26    Ok(removed)
27}
28
29#[cfg(test)]
30mod tests {
31    use super::cleanup_orphan_install_dirs;
32    use anyhow::Result;
33    use std::fs;
34    use tempfile::tempdir;
35
36    #[test]
37    fn cleanup_orphan_install_dirs_removes_existing_paths_and_ignores_missing_ones() -> Result<()> {
38        let root = tempdir().expect("temp dir");
39        let existing_orphan = root.path().join("Contoso.Orphan");
40        let missing_orphan = root.path().join("Contoso.Missing");
41
42        fs::create_dir_all(&existing_orphan).expect("create orphan directory");
43        fs::write(existing_orphan.join("tool.exe"), b"binary").expect("write orphan file");
44
45        let removed = cleanup_orphan_install_dirs(&[existing_orphan.clone(), missing_orphan])?;
46
47        assert_eq!(removed, 1);
48        assert!(!existing_orphan.exists());
49
50        Ok(())
51    }
52}